package com.soa.ocod;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.net.ssl.HttpsURLConnection;

/**
 * 
 * OdSession
 * 
 * This class is used to maintain a session with On Demand for performing web
 * services call.
 * 
 * @author  frederic.agneray@gmail.com
 * 
 */
public class OdSession {

  public static String sessionid = null;
  public static Date timeForSession = new Date();
  private static Logger log = Logger.getLogger(OdSession.class.getName());

  public static String getSessionId() {
    if (sessionid == null || isOld(timeForSession)) {
      login();
    }
    timeForSession.setTime(System.currentTimeMillis());
    System.out.println("used sessionId = " + sessionid);
    return sessionid;
  }

  /**
   * Log into a session with CRM On Demand
   */
  public static void login() {
    try {
      URL wsURL = new URL(OcodProxy.OCOD_URL + "?command=login");
      HttpsURLConnection wsConnection = (HttpsURLConnection) wsURL.openConnection();
      wsConnection.setRequestProperty("UserName", "MY/TEST");
      wsConnection.setRequestProperty("Password", "*********");
      wsConnection.setUseCaches(false);
      wsConnection.setRequestMethod("GET");
      // see if we got a successful response
      int res = wsConnection.getResponseCode();
      if (res == HttpURLConnection.HTTP_OK) {
        // get the session id from the cookie setting
        String cookie = getCookieFromHeaders(wsConnection);
        sessionid = isolateSessionId(cookie);
      }
      else
        log.severe("cannot login with given credentials");
    } catch (Exception e) {
      log.severe("Logon Exception generated :: " + e);
      sessionid = null;
    }
  }

  /**
   * Logoff the existing session from CRM On Demand
   */
  public static void logoff() {
    if (sessionid.length() == 0)
      return;
    try {

      URL wsURL = new URL(OcodProxy.OCOD_URL + "?command=logoff");
      HttpsURLConnection wsConnection = (HttpsURLConnection) wsURL.openConnection();

      wsConnection.addRequestProperty("Cookie", sessionid);
      wsConnection.setRequestMethod("GET");
      // see if we got a successful response
      if (wsConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        sessionid = "";
      }
    } catch (Exception e) {
      log.severe("Logon Exception generated :: " + e);
      sessionid = "";
    }
  }

  // return the header value (FAIL string for not found)
  private static String getCookieFromHeaders(HttpURLConnection wsConnection) {
    String headerName;
    String headerValue = "FAIL";
    for (int i = 0;; i++) {
      headerName = wsConnection.getHeaderFieldKey(i);
      if (headerName != null && headerName.equals("Set-Cookie")) {
        // found the Set-Cookie header (code assumes only one cookie is being
        // set)
        headerValue = wsConnection.getHeaderField(i);
        break;
      }
    }
    return headerValue;
  }

  private static String isolateSessionId(String cookie) {
    StringTokenizer st = new StringTokenizer(cookie, ";");
    String jsessionid = st.nextToken();
    st = new StringTokenizer(jsessionid, "=");
    st.nextToken();
    return st.nextToken();
  }

  private static boolean isOld(Date date) {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.MINUTE, -10);
    Date nowMinusTen = cal.getTime();
    return date.compareTo(nowMinusTen) < 0;
  }

  public static void main(String[] args) {
    OdSession.getSessionId();
    System.out.println("sessionid = " + sessionid);
  }

}